package cn.sciento.autoconfigure.platform;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import cn.sciento.resource.annoation.EnableSTongResourceServer;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import cn.sciento.platform.infra.properties.DataHierarchyProperties;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;


import cn.sciento.core.jackson.annotation.EnableObjectMapper;
import cn.sciento.core.util.CommonExecutor;
import cn.sciento.platform.infra.properties.PlatformProperties;


@ComponentScan(value = {"org.hippius.wd", "cn.sciento.platform.api", "cn.sciento.platform.app",
        "cn.sciento.platform.config", "cn.sciento.platform.domain", "cn.sciento.platform.infra"})
@EnableFeignClients({"cn.sciento.platform", "io.choerodon", "cn.sciento.plugin"})
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@EnableSTongResourceServer
@EnableObjectMapper
@EnableAsync
@EnableConfigurationProperties({PlatformProperties.class, DataHierarchyProperties.class})
public class PlatformAutoConfiguration {

    /**
     * 通用线程池
     */
    @Bean
    @Qualifier("commonAsyncTaskExecutor")
    public ThreadPoolExecutor commonAsyncTaskExecutor() {
        int coreSize = CommonExecutor.getCpuProcessors();
        int maxSize = coreSize * 8;
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                coreSize, maxSize,
                30, TimeUnit.MINUTES,
                new LinkedBlockingQueue<>(16),
                new ThreadFactoryBuilder().setNameFormat("CommonExecutor-%d").build(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );

        CommonExecutor.displayThreadPoolStatus(executor, "HpfmCommonExecutor");
        CommonExecutor.hookShutdownThreadPool(executor, "HpfmCommonExecutor");

        return executor;
    }

}
